using System.Collections.Generic;
using UnityEngine;


namespace HEFramework
{
    /// <summary>
    ///
    /// 音源播放器
    /// 
    /// ----------------------------------------
    /// 作者 hep
    /// 创建时间：2023-12-19 15:58:49
    /// ----------------------------------------
    /// </summary>
    public class AudioSourcePlayer : Singleton<AudioSourcePlayer>, ISingletonAwake, ISingletonUpdate
    {
        /// <summary>
        /// 背景音乐音量
        /// </summary>
        private float bgmVolume;

        /// <summary>
        /// 音效音量
        /// </summary>
        private float effectVolume;

        /// <summary>
        /// 背景音乐静音
        /// </summary>
        private bool bgmMute;

        /// <summary>
        /// 音效静音
        /// </summary>
        private bool effectMute;

        /// <summary>
        /// 背景音乐播放源列表
        /// </summary>
        private List<IAudioSource> bgmAudioSources = new();

        /// <summary>
        /// 2D音效播放源列表
        /// </summary>
        private List<IAudioSource> effect2DAudioSources = new();

        /// <summary>
        /// 3D音效播放源列表
        /// </summary>
        private List<IAudioSource> effect3DAudioSources = new();

        /// <summary>
        /// 音源挂载根节点
        /// </summary>
        private GameObject audioSourceRoot;


        public float BgmVolume => bgmVolume;

        public float EffectVolume => effectVolume;

        public bool BgmMute => bgmMute;

        public bool EffectMute => effectMute;


        /// <summary>
        /// 初始化
        /// </summary>
        public void Awake()
        {
            bgmVolume = 1;
            effectVolume = 1;
            bgmMute = false;
            effectMute = false;
            audioSourceRoot = GameObject.Find("AudioSource");
        }

        /// <summary>
        /// 帧更新
        /// </summary>
        public void Update()
        {
            for (int i = 0; i < bgmAudioSources.Count; i++)
            {
                bgmAudioSources[i].Update();
            }

            for (int i = 0; i < effect2DAudioSources.Count; i++)
            {
                effect2DAudioSources[i].Update();
            }

            for (int i = 0; i < effect3DAudioSources.Count; i++)
            {
                effect3DAudioSources[i].Update();
            }
        }

        /// <summary>
        /// 销毁
        /// </summary>
        protected override void Destroy()
        {
            for (int i = 0; i < bgmAudioSources.Count; i++)
            {
                bgmAudioSources[i].Dispose();
            }

            for (int i = 0; i < effect2DAudioSources.Count; i++)
            {
                effect2DAudioSources[i].Dispose();
            }

            for (int i = 0; i < effect3DAudioSources.Count; i++)
            {
                effect3DAudioSources[i].Dispose();
            }

            bgmAudioSources.Clear();
            effect2DAudioSources.Clear();
            effect3DAudioSources.Clear();
        }


        #region 背景音乐

        /// <summary>
        /// 设置背景音乐音量
        /// </summary>
        /// <param name="_value"></param>
        public void SetBGMVolum(float _value)
        {
            bgmVolume = _value;
            for (int i = 0; i < bgmAudioSources.Count; i++)
            {
                bgmAudioSources[i].Volume(bgmVolume);
            }
        }

        /// <summary>
        /// 设置背景音乐静音
        /// </summary>
        /// <param name="_value"></param>
        public void SetBGMMute(bool _value)
        {
            bgmMute = _value;
            for (int i = 0; i < bgmAudioSources.Count; i++)
            {
                bgmAudioSources[i].Mute(bgmMute);
            }
        }

        /// <summary>
        /// 添加背景音乐音源
        /// </summary>
        /// <returns></returns>
        public T AddBGMAudioSource<T>() where T : BGMAudioSource, new()
        {
            IAudioSource audioSource = null;
            for (int i = 0; i < bgmAudioSources.Count; i++)
            {
                if (!bgmAudioSources[i].IsUse)
                {
                    if (bgmAudioSources[i] is T)
                    {
                        audioSource = bgmAudioSources[i];
                        break;
                    }
                }
            }

            if (audioSource == null)
            {
                GameObject obj = new GameObject(typeof(T).FullName);
                obj.transform.SetParent(audioSourceRoot.transform);
                obj.transform.localPosition = Vector3.zero;
                audioSource = new T();
                audioSource.Awake(obj.AddComponent<AudioSource>());
                bgmAudioSources.Add(audioSource);
            }

            audioSource.Volume(bgmVolume);
            audioSource.Mute(bgmMute);
            audioSource.Use(true);
            return (T)audioSource;
        }

        #endregion


        #region 音效

        /// <summary>
        /// 设置音效音量
        /// </summary>
        /// <param name="_value"></param>
        public void SetEffectVolum(float _value)
        {
            effectVolume = _value;
            for (int i = 0; i < effect2DAudioSources.Count; i++)
            {
                effect2DAudioSources[i].Volume(effectVolume);
            }

            for (int i = 0; i < effect3DAudioSources.Count; i++)
            {
                effect3DAudioSources[i].Volume(effectVolume);
            }
        }

        /// <summary>
        /// 设置音效静音
        /// </summary>
        /// <param name="_value"></param>
        public void SetEffectMute(bool _value)
        {
            effectMute = _value;
            for (int i = 0; i < effect2DAudioSources.Count; i++)
            {
                effect2DAudioSources[i].Mute(effectMute);
            }

            for (int i = 0; i < effect3DAudioSources.Count; i++)
            {
                effect3DAudioSources[i].Mute(effectMute);
            }
        }

        /// <summary>
        /// 添加2D音效音源
        /// </summary>
        /// <returns></returns>
        public T AddEffect2DAudioSource<T>() where T : Effect2DAudioSource, new()
        {
            IAudioSource audioSource = null;
            for (int i = 0; i < effect2DAudioSources.Count; i++)
            {
                if (!effect2DAudioSources[i].IsUse)
                {
                    if (effect2DAudioSources[i] is T)
                    {
                        audioSource = effect2DAudioSources[i];
                        break;
                    }
                }
            }

            if (audioSource == null)
            {
                GameObject obj = new GameObject(typeof(T).FullName);
                obj.transform.transform.SetParent(audioSourceRoot.transform);
                obj.transform.localPosition = Vector3.zero;
                audioSource = new T();
                audioSource.Awake(obj.AddComponent<AudioSource>());
                effect2DAudioSources.Add(audioSource);
            }

            audioSource.Volume(effectVolume);
            audioSource.Mute(effectMute);
            audioSource.Use(true);
            return (T)audioSource;
        }

        /// <summary>
        /// 添加3D音效音源
        /// </summary>
        /// <returns></returns>
        public T AddEffect3DAudioSource<T>() where T : Effect3DAudioSource, new()
        {
            IAudioSource audioSource = null;
            for (int i = 0; i < effect3DAudioSources.Count; i++)
            {
                if (!effect3DAudioSources[i].IsUse)
                {
                    if (effect3DAudioSources[i] is T)
                    {
                        audioSource = effect3DAudioSources[i];
                        break;
                    }
                }
            }

            if (audioSource == null)
            {
                GameObject obj = new GameObject(typeof(T).FullName);
                obj.transform.transform.SetParent(audioSourceRoot.transform);
                obj.transform.localPosition = Vector3.zero;
                audioSource = new T();
                audioSource.Awake(obj.AddComponent<AudioSource>());
                effect3DAudioSources.Add(audioSource);
            }

            audioSource.Volume(effectVolume);
            audioSource.Mute(effectMute);
            audioSource.Use(true);
            return (T)audioSource;
        }

        #endregion


        /// <summary>
        /// 移除音频
        /// </summary>
        /// <param name="_audio"></param>
        public void RemoveAudioSource(IAudioSource _audio)
        {
            if (_audio is BGMAudioSource)
            {
                bgmAudioSources.Remove(_audio);
            }

            if (_audio is Effect2DAudioSource)
            {
                effect2DAudioSources.Remove(_audio);
            }

            if (_audio is Effect3DAudioSource)
            {
                effect3DAudioSources.Remove(_audio);
            }
        }
    }
}